﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.ComponentModel;
using ArgosDesktop.Design;
using System.Drawing.Design;
using System.IO;
using System.Diagnostics;

namespace ArgosDesktop
{
	internal class UserSettings : ApplicationSettingsBase
	{

		private UserSettings()
		{
			if (Directory.Exists(this.DataStorageFolder))
			{
				string logPath = string.Format(@"{0}\Logs", this.DataStorageFolder);
				if (!Directory.Exists(logPath))
				{
					try
					{
						Directory.CreateDirectory(logPath);
					}
					catch { }
				}

				if (Directory.Exists(logPath))
				{
					this.LogFolderPath = logPath;
				}
			}
		}

		private static UserSettings defaultInstance = ((UserSettings)(ApplicationSettingsBase.Synchronized(new UserSettings())));

		public static UserSettings Default
		{
			get { return defaultInstance; }
		}



		//-------------------------------------------------------------------
		// Not browsable properties

		#region public string AlertStorageFolder { get; }

		[Browsable(false)]
		public string AlertStorageFolder
		{
			get { return string.Format(@"{0}\Alerts", this.DataStorageFolder); }
		}

		#endregion
		
		#region public string DataStorageFolder { get; set; }

		public const string DataStorageFolderPropertyName = "DataStorageFolder";

		[UserScopedSetting]
		[Browsable(false)]
		[DefaultSettingValue("")]
		[DefaultValue(null)]
		public string DataStorageFolder
		{
			get { return (string)this[DataStorageFolderPropertyName]; }
			set { this[DataStorageFolderPropertyName] = value; }
		}

		#endregion

		#region public string PersistenceStorageFolder { get; }

		[Browsable(false)]
		public string PersistenceStorageFolder
		{
			get { return string.Format(@"{0}\Persistence", this.DataStorageFolder); }
		}

		#endregion
		
		#region public string TargetStorageFolder { get; }

		[Browsable(false)]
		public string TargetStorageFolder
		{
			get { return string.Format(@"{0}\Targets", this.DataStorageFolder); }
		}

		#endregion



		//-------------------------------------------------------------------
		// Alerts

		#region public int MaxAlertCount { get; set; }

		public const string MaxAlertCountPropertyName = "MaxAlertCount";

		[Category("Alerts")]
		[DisplayName("Max Alert Count")]
		[Description("The maximum number of alerts to keep. When there are more alerts than the value specified in this property, the oldest are deleted. If this property is set to 0, all alerts are kept.")]
		[UserScopedSetting]
		[DefaultSettingValue("100")]
		[DefaultValue(100)]
		public int MaxAlertCount
		{
			get { return (int)this[MaxAlertCountPropertyName]; }
			set { if (value < 0) { throw new ArgumentOutOfRangeException(MaxAlertCountPropertyName, "The alert count cannot be less than 0."); } this[MaxAlertCountPropertyName] = value; }
		}
		
		#endregion



		//-------------------------------------------------------------------
		// Behaviour

		#region public bool AutoStart { get; set; }

		public const string AutoStartPropertyName = "AutoStart";

		[Category("Behaviour")]
		[DisplayName("Auto Start")]
		[Description("Specifies whether Argos Desktop should automatically start when you log on to Windows.")]
		[UserScopedSetting]
		[DefaultSettingValue("False")]
		[DefaultValue(false)]
		public bool AutoStart
		{
			get { return (bool)this[AutoStartPropertyName]; }
			set { this[AutoStartPropertyName] = value; }
		}

		#endregion
		
		#region public bool StartMinimized { get; set; }

		public const string StartMinimizedPropertyName = "StartMinimized";

		[Category("Behaviour")]
		[DisplayName("Start Minimized")]
		[Description("Specifies whether Argos Desktop should minimized itself to the system tray when starting.")]
		[UserScopedSetting]
		[DefaultSettingValue("False")]
		[DefaultValue(false)]
		public bool StartMinimized
		{
			get { return (bool)this[StartMinimizedPropertyName]; }
			set { this[StartMinimizedPropertyName] = value; }
		}

		#endregion



		//-------------------------------------------------------------------
		// Logging

		#region public bool EnableLogging { get; set; }

		public const string EnableLoggingPropertyName = "EnableLogging";

		[Category("Logging")]
		[DisplayName("Enable Logging")]
		[Description("Specifies whether to enable or disable logging in the application.")]
		[UserScopedSetting]
		[DefaultSettingValue("False")]
		[DefaultValue(false)]
		public bool EnableLogging
		{
			get { return (bool)this[EnableLoggingPropertyName]; }
			set { this[EnableLoggingPropertyName] = value; }
		}

		#endregion

		#region public string LogFolderPath { get; set; }

		public const string LogFolderPathPropertyName = "LogFolderPath";

		[Category("Logging")]
		[DisplayName("Logging Folder")]
		[Description("Specifies the path to the folder where log files will be stored when logging is enabled.")]
		[UserScopedSetting]
		[DefaultSettingValue("")]
		[DefaultValue("")]
		[Editor(typeof(FolderPathEditor), typeof(UITypeEditor))]
		public string LogFolderPath
		{
			get { return (string)this[LogFolderPathPropertyName]; }
			set
			{
				if (!Directory.Exists(value))
				{
					throw new ArgumentException("The given directory does not exist.", "LogFolderPath");
				}
				this[LogFolderPathPropertyName] = value;
			}
		}

		#endregion

		#region public SourceLevels LoggingLevel { get; set; }

		public const string LoggingLevelPropertyName = "LoggingLevel";

		[Category("Logging")]
		[DisplayName("Logging Level")]
		[Description("Specifies the level of logging.")]
		[UserScopedSetting]
		[DefaultSettingValue("Warning")]
		[DefaultValue(SourceLevels.Warning)]
		public SourceLevels LoggingLevel
		{
			get { return (SourceLevels)this[LoggingLevelPropertyName]; }
			set { this[LoggingLevelPropertyName] = value; }
		}

		#endregion

	}
}
